package com.zr.plant.service.impl;

import com.zr.meiju.StatusEnum;
import com.zr.planclass.pojo.PlanClass;
import com.zr.plant.mapper.PlantMapper;
import com.zr.plant.pojo.*;
import com.zr.plant.service.PlantService;
import com.zr.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by 86151 on 2019/6/14.
 */
@Service
@Slf4j
public class PlantServiceImpl implements PlantService {
    @Autowired
    private PlantMapper plantMapper;

    /**
     * 添加
     * @param plantAddVoList
     * @return
     */
    @Override
    @Transactional
    public ResultVo addPlant(List<PlantAddVo> plantAddVoList) {
        //逻辑验证
        ResultVo assigment = assigment(plantAddVoList);
        if (!assigment.isSuccess()){
            return assigment;
//            return ResultBuildVo.error(assigment.getErrorMessage(),assigment.getErrorCode());
        }
        //给数据库中的创建时间和修改时间等信息赋值
        List<PlantClass> plantClassList = new ArrayList<>();
        for (PlantAddVo plantClassAddVo1 :plantAddVoList){
            PlantClass plantClass = new PlantClass();
            Date nowDate = new Date();
            plantClass.setCreateTime(nowDate);
            plantClass.setCreateName("小明");
            plantClass.setUpdateTime(nowDate);
            plantClass.setUpdateName("小明");
            BeanUtils.copyProperties(plantClassAddVo1,plantClass);
            plantClassList.add(plantClass);
        }
        plantMapper.addPlant(plantClassList);
        return ResultBuildVo.success(plantClassList);
    }

    /**
     * 修改接口
     * @param plantUpdateVo
     * @return
     */
    @Transactional
    public ResultVo updatePlant(PlantUpdateVo plantUpdateVo) {
        //逻辑验证=禁用状态下才允许修改
        ResultVo assigment = assigmentUpdate(plantUpdateVo);
        if (!assigment.isSuccess()){
            return assigment;
        }
        //给数据库中的创建时间和修改时间等信息赋值
        PlantClass plantClass = new PlantClass();
        Date nowDate = new Date();
        plantClass.setUpdateTime(nowDate);
        plantClass.setUpdateName("小明");
        //把左边对象的数据赋值给右边对象的数据
        //注意必须相同参数名称和相同参数类型才能自动进行赋值
        BeanUtils.copyProperties(plantUpdateVo, plantClass);
        plantMapper.updatePlant(plantClass);
        return ResultBuildVo.success(plantUpdateVo);
    }

    /**
     * 修改状态接口
     * @param plantStatusVo
     * @param
     * @return
     */
    @Transactional
    public ResultVo updateStatus(PlantStatusVo plantStatusVo) {
        //逻辑验证
        //验证数据是否存在
        PlantClass queryPlantById = plantMapper.queryPlantById(plantStatusVo.getId());
        if (queryPlantById==null){
            return ResultBuildVo.error("修改数据不存在！","500");
        }
        //给数据库中的创建时间和修改时间等信息赋值
        PlantClass plantClass = new PlantClass();
        Date nowDate = new Date();
        plantClass.setUpdateTime(nowDate);
        plantClass.setUpdateName("小明");
        //把左边对象的数据赋值给右边对象的数据
        //注意必须相同参数名称和相同参数类型才能自动进行赋值
        BeanUtils.copyProperties(plantStatusVo, plantClass);
        plantMapper.updateStatus(plantClass);
        return ResultBuildVo.success(plantClass);
    }

    public ResultVo assigmentUpdate(PlantUpdateVo plantUpdateVo){
        //验证数据是否存在
        List<PlantClass> plantClasses = plantMapper.queryByCode(plantUpdateVo.getLegalPlantCode());
        if (CollectionUtils.isEmpty(plantClasses)){
            return ResultBuildVo.error("修改数据不存在！","500");
        }
       /* //禁用状态下才允许修改
        if (plantClass.getStatus()== StatusEnum.QIYONG.getStatusValue()){
            return ResultBuildVo.error("禁用状态才能修改！","500");
        }*/
        return ResultBuildVo.success(plantUpdateVo);
    }

    @Override
    public ResultVo<List<Legalperson>> queryDown(Integer uid) {
        if (uid==null){
            return ResultBuildVo.error("查询时ID不能为空！","500");
        }
        List<Legalperson> legalpersonList = plantMapper.queryLegalPersonByUid(uid);
        return ResultBuildVo.success(legalpersonList);
    }

    /**
     * 工厂查看接口
     */
    @Override
    public ResultVo<PlantClass> queryPlantById(Integer id) {
        PlantClass queryPlantById = plantMapper.queryPlantById(id);
        if (queryPlantById==null){
            return ResultBuildVo.error("查看数据不存在！","500");
        }
        return ResultBuildVo.success(queryPlantById);
    }

    /**
     * 分页查询
     * @param plantSelectVo
     * @return
     */
    @Override
    public ResultVo<AllRecords> queryPage(PlantSelectVo plantSelectVo) {
        //查询数据
        List<PlantClass> plantClassList = plantMapper.queryPage(plantSelectVo);
        //查询数量
        int count =  plantMapper.queryCount(plantSelectVo);
        //把当前页、每页大小、总页数、总条数、数据统一放入到AllRecords返回
        AllRecords allRecords = new AllRecords();
        allRecords.setPageIndex(plantSelectVo.getPageIndex());
        allRecords.setPageSize(plantSelectVo.getPageSize());
        allRecords.setTotalNumber(count);
        allRecords.resetTotalNumber(count);
        allRecords.setDataList(plantClassList);
        return ResultBuildVo.success(allRecords);
    }
    /**
     * 法人下拉框
     */

    @Override
    public ResultVo<List<LegalPersonResultVo>> ofCurrentUser() {
        List<LegalPersonResultVo> legalPersonResultVos = plantMapper.queryLegalPersons();
        return ResultBuildVo.success(legalPersonResultVos);
    }

    /**
     * 导入逻辑
     * @param file
     * @return
    1.给用户提供导入模板
    2.提示版本问题，询问产品经理支持哪种版本的导入格式，2007版本的导入模板，根据版本不同，poi导入技术的读取方式不同
    3.模板是否是需要导入的模板，验证模板是否正确
    4.格式问题，必须保持统一格式，统一为字符串格式导入
    5.验证不为空字段是否为空
    6.验证字符长度是否符合需求
    7.验证数据是否存在也就是是否合法
    8.验证数据是否重复
    9.对于需要转换的数据进行数据转换，比如数据库存的数据为数字格式，用户输入的为汉字，需要把汉字转换为数字存储*/
    @Override
    public ResultVo importPlanClass(MultipartFile file)throws Exception {
        if (file==null){
            return ResultBuildVo.error("导入信息不存在","500");
        }
        if (!file.getOriginalFilename().contains("xlsx")){
            return ResultBuildVo.error("只能导入2007版excel文件！","500");
        }
        /*模板是否是需要导入的模板，验证模板是否正确.导入数据到list集合中
        */
        ResultVo<List<PlantAddVo>> listResultVo = importData(file);
        if (!listResultVo.isSuccess()){
            return listResultVo;
        }
      /*  4.格式问题，必须保持统一格式，统一为字符串格式导入 5.验证不为空字段是否为空6.验证字符长度是否符合需求*/
        ResultVo validate = validate(listResultVo.getData());
        if (!validate.isSuccess()){
            return validate;
        }
      /*  7.验证数据是否存在也就是是否合法 8.验证数据是否重复9.对于需要转换的数据进行数据转换，比如数据库存的数据为数字格式，用户输入的为汉字，需要把汉字转换为数字存储*//**/
        ResultVo resultVo = validate2(listResultVo.getData());
        if (!resultVo.isSuccess()){
            return resultVo;
        }
        //入库操作
        ResultVo resultVo1 = addPlant(listResultVo.getData());
        if (!resultVo1.isSuccess()){
            return resultVo1;
        }
        return listResultVo;
    }


    /**
     * 导出
     //1.定义一个导出模板
     //2.从数据库中查询出将要导出的数据
     //3.把从数据库中查询出的数据赋值给导出模板
     //4.对需要转化的数据进行转化
     //5.在浏览器生成一个文件
     */
    @Override
    public ResultVo exportExcel(HttpServletResponse response, PlantSelectVo plantSelectVo)throws Exception {
        //从数据库中查询出将要导出的数据
        List<PlantClass> plantClassList = plantMapper.queryBySelectVo(plantSelectVo);
        for (PlantClass plantClass:plantClassList){
            plantClass.setEnabledName(StatusEnum.getName(plantClass.getEnabled()==true?1:0));
        }
        //限制，默认只允许导出10000条数据
        int count = plantMapper.queryCount(plantSelectVo);
        if (count>10000){
            return ResultBuildVo.error("默认只允许导出10000条数据！请增加条件导出","500");
        }
        //获取响应输出流
        ServletOutputStream out = response.getOutputStream();
        //给输出文件设置名称
        POIClass.toPackageOs(response, "法人工厂导出");
        //读取模板中的数据
        InputStream in = ExportUtil.toPackageIn("templates/法人工厂.xlsx");
        //根据模板的数据、把查询出来的数据给摸版SHeet1组中的数据赋值、把excel输出到浏览器上
        writeDataToExcel(in, "Sheet1", plantClassList, out);
        if (in != null) {
            in.close();
            out.close();
        }
        return null;
    }

    // 由于此方法不能通用, 所以单独写在这里
    private void writeDataToExcel(InputStream in, String sheetName,
                                  List<PlantClass> resultList, ServletOutputStream out) throws Exception {
        //POi读取模板
        XSSFWorkbook wb = new XSSFWorkbook(in);
        //读取sheet1中的数据
        Sheet sheet = wb.getSheet(sheetName);
        if (sheet != null) {
            //向sheet1中赋值，设置样式
            toResultListValueInfo( sheet, resultList);
        }
        //把数据写入到输出流中
        wb.write(out);
        //关闭poi方法
        wb.close();
    }

    /**
     * 插入excel表中项目信息
     *
     * @param sheet
     */
    private void toResultListValueInfo(Sheet sheet, List<PlantClass> plantList) {
        //从第五行开始赋值
        int row_column = 4;
        //遍历数据集合
        for (PlantClass obj : plantList) {
            //创建一行的方法
            Row row = sheet.createRow(row_column);
            // 给第一列序号赋值赋值
            POIClass.toCellValue(row,0, obj.getId() + "");
            // 给第二列编码赋值
            POIClass.toCellValue(row, 1, obj.getLegalPlantCode() + "");
            // 给第3列名称赋值
            POIClass.toCellValue(row, 2, obj.getLegalPersonCode() + "");
            // 给状态赋值
            POIClass.toCellValue(row, 3, obj.getEnabledName() + "");
            //给描述赋值
            POIClass.toCellValue(row, 4, obj.getLegalPlantDec() + "");
            row_column++;
        }
    }

    public ResultVo validate2(List<PlantAddVo> plantImportVoList){
        /*  7.验证数据是否存在也就是是否合法 8.验证数据是否重复9.对于需要转换的数据进行数据转换，比如数据库存的数据为数字格式，用户输入的为汉字，需要把汉字转换为数字存储*//**/
        /*Set<String> codeSet = new HashSet<>();
        for (PlanClassImportVo planClassImportVo:planClassImportVoList){
            codeSet.add(planClassImportVo.getCode());
        }
        if (codeSet.size()!=planClassImportVoList.size()){
            return ResultBuildVo.error("存在重复的编码信息！","500");
        }*/

        List<String> codeList = new ArrayList<>();
        for (PlantAddVo plantImportVo:plantImportVoList){
            codeList.add(plantImportVo.getLegalPlantCode());
        }
        List<String> newList = new ArrayList<>();
        List<String> repeatList = new ArrayList<>();
        for (String code :codeList){
            if (newList.contains(code)){
                repeatList.add(code);
            }else{
                newList.add(code);
            }
        }
        if (repeatList.size()>0){
            return ResultBuildVo.error("存在重复的编码信息！重复的编码信息为："+repeatList,"500");
        }
        //验证用户输入的是否是启用禁用
        for (PlantAddVo planClassImportVo:plantImportVoList){

            System.out.println(planClassImportVo.getEnabledName());
            System.out.println(StatusEnum.getValue(planClassImportVo.getEnabledName()));
            if (StatusEnum.getValue(planClassImportVo.getEnabledName())==null){
                return ResultBuildVo.error("状态只能是启用或者禁用"+repeatList,"500");
            }else {
                planClassImportVo.setEnabled(StatusEnum.getValue(planClassImportVo.getEnabledName())==1?true:false);
            }
        }
        return ResultBuildVo.success(plantImportVoList);
    }

    public ResultVo validate(List<PlantAddVo> plantImportVoList){
        /*
        5.验证不为空字段是否为空
        6.验证字符长度是否符合需求*/
        for (PlantAddVo plantImportVo:plantImportVoList){
            if (StringUtils.isEmpty(plantImportVo.getLegalPlantCode())){
                return ResultBuildVo.error("工厂编码不能为空！","500");
            }else {
                if (plantImportVo.getLegalPlantCode().length()>20){
                    return ResultBuildVo.error("工厂编码长度不能大于20个字节！","500");
                }
            }
            if (StringUtils.isEmpty(plantImportVo.getLegalPersonCode())){
                return ResultBuildVo.error("法人编码不能为空！","500");
            }else {
                if (plantImportVo.getLegalPersonCode().length()>20){
                    return ResultBuildVo.error("法人编码长度不能大于20个字节！","500");
                }
            }
            if (StringUtils.isEmpty(plantImportVo.getEnabledName())){
                return ResultBuildVo.error("状态不能为空！","500");
            }else {
                if (plantImportVo.getEnabledName().length()>20){
                    return ResultBuildVo.error("状态长度不能大于20个字节！","500");
                }
            }
            if (!StringUtils.isEmpty(plantImportVo.getLegalPlantDec())){
                if (plantImportVo.getLegalPlantDec().length()>50){
                    return ResultBuildVo.error("描述长度不能大于50个字节！","500");
                }
            }
        }
        return ResultBuildVo.success(plantImportVoList);
    }
    public  ResultVo<List<PlantAddVo>> importData(MultipartFile file)throws Exception{
        //poi核心类，用来读取excel表格中的数据
        XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());
        //获取单元格中的信息 at0是获取sheet1中的数据。
        XSSFSheet sheet = workbook.getSheetAt(0);
        System.out.println(sheet.getRow(sheet.getFirstRowNum()).getCell(0));
        //验证第一列第一行的表格标头信息是否为 “询价单导入”，如果不是，提示模板错误。
        if (!String.valueOf(sheet.getRow(sheet.getFirstRowNum()).getCell(0)).equals("法人工厂")) {
            return ResultBuildVo.error("模板错误，请检查模板！","500");
        }
        List<PlantAddVo> inquirySpareDetailVoList = new ArrayList<>();
        //遍历excel表格中的所有数据，从第五行开始读取，没有数据时终止遍历。
        for (int i = sheet.getFirstRowNum() + 4; i <= sheet.getLastRowNum(); i++) {
            //读取每一行的数据
            XSSFRow xssfRow = sheet.getRow(i);
            if(xssfRow!=null) {
                //验证第一列数据、第二列、第三列数据是否为空
                System.out.println(String.valueOf(xssfRow.getCell(0)).trim());
                System.out.println(String.valueOf(xssfRow.getCell(1)).trim());
                System.out.println(String.valueOf(xssfRow.getCell(2)).trim());
                if ((!StringUtils.isEmpty(String.valueOf(xssfRow.getCell(1)).trim()))||
                        (!StringUtils.isEmpty(String.valueOf(xssfRow.getCell(2)).trim())) ||
                        (!StringUtils.isEmpty(String.valueOf(xssfRow.getCell(3)).trim()))
                        ) {
                    //把每一行的数据放入到实体类中
                    PlantAddVo inquiryImportVo = build(xssfRow);
                    //把实体类中的数据放入到list集合中
                    inquirySpareDetailVoList.add(inquiryImportVo);
                }
            }
        }

        return ResultBuildVo.success(inquirySpareDetailVoList);
    }
    private PlantAddVo build(XSSFRow xssfRow) throws Exception {
        PlantAddVo addVO = new PlantAddVo();
        addVO.setLegalPlantCode(String.valueOf(xssfRow.getCell(1)).trim());
        addVO.setLegalPersonCode(String.valueOf(xssfRow.getCell(2)).trim());
        addVO.setEnabledName(String.valueOf(xssfRow.getCell(3)).trim());
        addVO.setLegalPlantDec(String.valueOf(xssfRow.getCell(4)).trim());
        return addVO;
    }

    /* @Override
     public ResultVo<PlantClass> queryPlanClassById(Integer id) {
         if (id==null){
             return ResultBuildVo.error("查看时id不能为空！","500");
         }
         PlantClass plantClass = planClassMapper.queryById(id);
         if (plantClass ==null){
             return ResultBuildVo.error("查看对象不存在！","500");
         }
         return ResultBuildVo.success(plantClass);
     }


 */
//    public ResultVo assigment(PlantAddVo plantAddVo){
//        //        1.验证工厂编码是否已经存在
//        List<PlantClass> plantClassesCode = plantMapper.queryByCode(plantAddVo.getLegalPlantCode());
//        if (!CollectionUtils.isEmpty(plantClassesCode)){
//            return ResultBuildVo.error("已经存在工厂编码！","500");
//        }
////        2.验证法人编码是否存在
//        List<Legalperson> legalpersonList = plantMapper.queryLegalPersonByCode(plantAddVo.getLegalPersonCode());
//        if (CollectionUtils.isEmpty(legalpersonList)){
//            return ResultBuildVo.error("法人信息不存在！","500");
//        }
//        return ResultBuildVo.success(plantAddVo);
//    }
    public ResultVo assigment(List<PlantAddVo> plantAddVoList){
        List<String> codeList = new ArrayList<>();
        List<String> nameList = new ArrayList<>();
        for (PlantAddVo planClassAddVo:plantAddVoList){
            codeList.add(planClassAddVo.getLegalPlantCode());
            nameList.add(planClassAddVo.getLegalPersonCode());
        }
        //        1.验证编码是否已经存在
//        List<PlanClass> planClassesCode = planClassMapper.queryByCode(planClassAddVo.getCode());
        List<String> plantCode = plantMapper.queryByCodes(codeList);
        if (!CollectionUtils.isEmpty(plantCode)){
            return ResultBuildVo.error("已经存在编码！存在的编码为："+plantCode,"500");
        }
//        1.验证名称是否已经存在
//        List<PlanClass> planClassesName = planClassMapper.queryByName(planClassAddVo.getName());
        List<String> plantName = plantMapper.queryByNames(nameList);
        if (!CollectionUtils.isEmpty(plantName)){
            return ResultBuildVo.error("已经存在名称！存在的编码为："+plantName,"500");
        }
        return ResultBuildVo.success(plantAddVoList);
    }
}
